package com.his.invdrug.service.Imp;

import com.his.invdrug.dao.InvDrugStorageMapper;
import com.his.invdrug.entity.InvDrugStorage;
import com.his.invdrug.entity.InvDrugStorageKey;
import com.his.invdrug.service.InvDrugStorageService;
import com.his.invdrug.vo.InvDrugHeaderItemVo;
import com.his.invdrug.vo.InvDrugStorageVo;
import com.xiao.common.exception.HisExecption;
import com.xiao.common.util.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;

@Service
public class InvDrugStorageServiceImpl implements InvDrugStorageService {
    @Autowired
    private InvDrugStorageMapper invDrugStorageMapper;

    //synchronized 修饰同步方法，避免同时修改结存的情况出现
    @Override
    public synchronized void  controlStorage(InvDrugHeaderItemVo invDrugHeaderItemVo) {
        //组装结存数据
        InvDrugStorageVo invDrugStorageVo=new InvDrugStorageVo();
        invDrugStorageVo.setOrgidPl(invDrugHeaderItemVo.getOrgidPl());//本地机构
        invDrugStorageVo.setHerderItemId(invDrugHeaderItemVo.getId());//库单项目唯一ID
        invDrugStorageVo.setItemid(invDrugHeaderItemVo.getItemid());//项目ID
        invDrugStorageVo.setBatchcode(invDrugHeaderItemVo.getBenchcode());//批次号
        invDrugStorageVo.setFactor(invDrugHeaderItemVo.getFactor());//系数（基本单位和库房单位的换算系数）
        invDrugStorageVo.setStorage(invDrugHeaderItemVo.getQuantity());//操作数量
        invDrugStorageVo.setStop((short)0);
        //价格信息
        invDrugStorageVo.setStorageC(invDrugHeaderItemVo.getCostprice());
        invDrugStorageVo.setStorageP(invDrugHeaderItemVo.getPurchaseprice());
        invDrugStorageVo.setStorageS(invDrugHeaderItemVo.getSalesprice());
        invDrugStorageVo.setStorageW(invDrugHeaderItemVo.getWholesalesprice());
        invDrugStorageVo.setInvaliddate(invDrugHeaderItemVo.getValidityDate());//有效期
        //通过主键获取结存信息
        InvDrugStorage invDrugStorage =selectBykey(invDrugStorageVo);
        if(null==invDrugStorage){//没有结存信息 新增
            insert(invDrugStorageVo);
        }else{//修改
            //为了严谨性，这里核实一下价格、系数、有效期等数据是否统一
            boolean flag=true;
            flag=flag?invDrugStorageVo.getFactor().compareTo(invDrugStorage.getFactor())==0:flag;
            flag=flag?invDrugStorageVo.getStorageC().compareTo(invDrugStorage.getStorageC())==0:flag;
            flag=flag?invDrugStorageVo.getStorageP().compareTo(invDrugStorage.getStorageP())==0:flag;
            flag=flag?invDrugStorageVo.getStorageS().compareTo(invDrugStorage.getStorageS())==0:flag;
            flag=flag?invDrugStorageVo.getStorageW().compareTo(invDrugStorage.getStorageW())==0:flag;
            flag=flag?invDrugStorageVo.getInvaliddate().getTime()==invDrugStorage.getInvaliddate().getTime():flag;
            if(flag){//信息一致
                //前端会判断结存是否足够，但是不能保证数据不会延迟或同时执行库存操作的情况
                //考虑逻辑严谨，这里每次存入的时候就判断一下结存；方法是用同步处理，避免特殊情况同时修改结存导致结存为负数
                BigDecimal newStorage=invDrugStorage.getStorage().add(invDrugHeaderItemVo.getQuantity());
                if(newStorage.compareTo(BigDecimal.ZERO)<0){//结存为负数
                    throw HisExecption.serverErrException("结存小于出库数量，原因可能为其他出库操作了该结存。请刷新界面重新核实结存数量后再进行操作！");
                }else{//结存大于等于0
                    invDrugStorageVo.setStorage(newStorage);//结存 基本单位数量
                    update(invDrugStorageVo);
                }
            }else{//信息不一致
                throw HisExecption.serverErrException("入库项目在流转过程中出现了信息不一致，请联系管理员查明原因");
            }
        }
    }

    @Override
    public boolean temNumCompareStorage(InvDrugStorageKey invDrugStorageKey, BigDecimal itemNum) {
        InvDrugStorage invDrugStorage=invDrugStorageMapper.selectByPrimaryKey(invDrugStorageKey);
        return invDrugStorage.getStorage().add(itemNum).compareTo(BigDecimal.ZERO)>=0;
    }

    /**
     *通过主键（本地机构，项目唯一码）查询结存信息
     */
    private InvDrugStorage selectBykey(InvDrugStorageVo invDrugStorageVo){
        InvDrugStorageKey invDrugStorageKey= BeanUtil.copyBean(invDrugStorageVo,InvDrugStorageKey.class);
        return invDrugStorageMapper.selectByPrimaryKey(invDrugStorageKey);
    }
    /**
     *新增结存信息
     */
    private void insert(InvDrugStorageVo invDrugStorageVo){
        InvDrugStorage invDrugStorage= BeanUtil.copyBean(invDrugStorageVo,InvDrugStorage.class);
        invDrugStorage.setUpdatetime(new Date());
        invDrugStorageMapper.insertSelective(invDrugStorage);
    }
    /**
     *通过主键（本地机构，项目唯一码）修改结存信息
     */
    private void update(InvDrugStorageVo invDrugStorageVo){
        InvDrugStorage invDrugStorage= BeanUtil.copyBean(invDrugStorageVo,InvDrugStorage.class);
        invDrugStorage.setUpdatetime(new Date());
        invDrugStorageMapper.updateByPrimaryKeySelective(invDrugStorage);
    }
}
